﻿ //Inicio Funciones propias de GoogleMap (Esta sección debe ser remplazada cuando se trabaje BingMap)

function MapControl() {

    var map;
    var directionsDisplay;
    var infoWindowStop;
    var geocoder;
    var polyRoute;
    var polygono;
    var car;
    var originImeiMarker;
    var pathPolygono;
    var polygonoMarkers;
    var directionsService;
    var routes;
    var clientsRoutes;
    var directionsDisplayClientsRoutes;
    var geocoderOrigin;
    var geocoderDestination;

    this.initializeMap = function() {

        this.directionsDisplay = new google.maps.DirectionsRenderer();
        this.directionsDisplay.setOptions({ preserveViewport: true });

        this.directionsDisplayClientsRoutes = new google.maps.DirectionsRenderer();
        this.directionsDisplayClientsRoutes.setOptions({ preserveViewport: true });
        
        this.geocoderOrigin = new google.maps.Geocoder();
        this.geocoderDestination = new google.maps.Geocoder();
        this.infoWindowStop = new google.maps.InfoWindow();
        this.pathPolygono = new google.maps.MVCArray;
        this.geocoder = new google.maps.Geocoder();
        this.polygonoMarkers = [];
        this.directionsService = new google.maps.DirectionsService();
        this.routes = [];
        this.clientsRoutes = [];

        var myLatLng = new google.maps.LatLng(10.060727, -84.43785);
        var myOptions = {
            center: myLatLng,
            zoom: 12,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        
        this.map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

        this.car = this.addMarker(null, null, null);


        this.initializeOriginImeiMarker();
        

    }

    this.initializeOriginImeiMarker = function()
    {
        this.originImeiMarker = this.addMarker(null, null, null);
        this.originImeiMarker.setDraggable(true);
        // Add dragging event listeners.
        /*google.maps.event.addListener(this.originImeiMarker, 'dragstart', function () {
            updateDirectionMarker('Dragging...');
        });

        google.maps.event.addListener(this.originImeiMarker, 'drag', function () {
            //updateMarkerStatus('Dragging...');
        });*/

        google.maps.event.addListener(this.originImeiMarker, 'dragend', function () {
            //updateMarkerStatus('Drag ended');
            var index = -1;
            index = existImeiIntoTheList(global.imei, globalList.imei);
            if (index != -1) {
                globalList.imei[index].position = objMapControl.originImeiMarker.position;
                globalList.imei[index].address = objMapControl.originImeiMarker.position.lat() + "," + objMapControl.originImeiMarker.position.lng();
            }
        });
    }

    this.showHistoryRoute = function()
    {
        this.directionsDisplay.setMap(this.map);
    }
    
    this.hideHistoryRoute = function()
    {
        this.directionsDisplay.setMap(null);
    }

    this.showClientsRoutes = function () {
        this.directionsDisplayClientsRoutes.setMap(this.map);
    }

    this.hideClientsRoutes = function () {
        this.directionsDisplayClientsRoutes.setMap(null);
    }

    this.drawRoute = function(route)
    {
        this.directionsDisplay.setDirections(route);
    }

    this.drawRouteClient = function (route) {
        this.directionsDisplayClientsRoutes.setDirections(route);
    }
    
    this.addInfoWindow = function()
    {
        return new google.maps.InfoWindow();
    }

    this.setinfoWindowStopContent = function (content) {
        this.infoWindowStop.setContent(content);
    }

    this.infoWindowStopOpen = function (marker) {
        this.infoWindowStop.open(this.map, marker);
    }

    this.addCustomerMarker = function() {
        return new google.maps.Marker({ map: this.map, draggable: true });
    }

    this.centerMap = function(position) {
        this.map.setCenter(position);
    }

    this.zoomMap = function (zoom) {
        this.map.setZoom(zoom);
    }

    this.addStopMarker = function (image, position, title)
    {
        var stopMarker = new google.maps.Marker({ map: this.map, icon: image, position: position, title: title });

        google.maps.event.addListener(stopMarker, 'click', function (event) {
            for (i = 0; i < globalList.stopsMarkers.length; i++) {
                if (objMapControl.getPositionXtoString(objMapControl.getPositionMarker(globalList.stopsMarkers[i].stopMarker)) == objMapControl.getPositionXtoString(event.latLng) && objMapControl.getPositionYtoString(objMapControl.getPositionMarker(globalList.stopsMarkers[i].stopMarker)) == objMapControl.getPositionYtoString(event.latLng)) {
                    objMapControl.setinfoWindowStopContent('<b>Hora en la que se detiene: ' + globalList.stopsMarkers[i].initialTimeStop + '<br/>' + 'Hora en la que continúa: ' + globalList.stopsMarkers[i].finalTimeStop);
                    objMapControl.infoWindowStopOpen(globalList.stopsMarkers[i].stopMarker);
                }
            }
        });

        return stopMarker;
    }

    this.getDirectionFromPosition = function (latlng) {
        this.geocoder.geocode({ 'latLng': latlng }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                if (results[1]) {
                    getlbDirection().innerText = results[0].formatted_address;
                }
            } else {
                //alert("Geocoder failed due to: " + status);
            }
        });
    }

    this.initializePolygono = function () {
        this.polygono = new google.maps.Polygon({
            strokeWeight: 3,
            fillColor: '#5555FF'
        });

        this.polyRoute = new google.maps.Polyline({
            strokeColor: '#000000',
            strokeOpacity: 1.0,
            strokeWeight: 5
        });

        this.polyRoute.setMap(this.map);
        this.polygono.setMap(this.map);
        this.polygono.setPaths(new google.maps.MVCArray([this.pathPolygono]));
    }

    this.clearGeoFenceMarkers = function (clearAll) {

        this.pathPolygono.clear();

        var totalMarkers = this.polygonoMarkers.length;

        for (k = 0; k < totalMarkers; k++) {
            this.polygonoMarkers[k].setMap(null);
        }

        for (k = 0; k < totalMarkers; k++) {
            this.polygonoMarkers.pop();
        }

        if (clearAll)
        {
            for (k = 0; k < globalList.geoFence.length; k++) {
                globalList.geoFence[k].checked = false;
                getGeoFenceGrid().clearSelectedItems();
            }
        }

    }

    this.setPositionMarker = function (marker, position) {
        marker.setPosition(position);
    }

    this.getPositionMarker = function (marker) {
        return marker.position;
    }



    this.setVisibleMarker = function (marker, status){
        marker.setVisible(status);
    }

    this.setIconMarker = function (marker, image) {
        marker.setIcon(image);
    }

    this.setTitleMarker = function (marker, title) {
        marker.setTitle(title);
    }

    this.getTitleMarker = function(marker){
        return marker.getTitle();
    }

    this.addListenerClic = function () {
        google.maps.event.addListener(this.map, 'click', this.addGeoFenceMarkersClic);
    }

    this.clearListenerClic = function () {
        google.maps.event.clearListeners(this.map, 'click');
        getCkbCustomer().enabled = false;
        getCkbEnableDisableGeoFence().enabled = false;
    }

    this.addGeoFenceMarkersClic = function (event) {
        objMapControl.pathPolygono.insertAt(objMapControl.pathPolygono.length, event.latLng);

        var lmarker = new google.maps.Marker({
            position: event.latLng,
            map: objMapControl.map,
            draggable: true
        });
        objMapControl.polygonoMarkers.push(lmarker);


        lmarker.setTitle("#" + objMapControl.pathPolygono.length);

        google.maps.event.addListener(lmarker, 'click', function () {
            lmarker.setMap(null);
            for (var i = 0, I = objMapControl.polygonoMarkers.length; i < I && objMapControl.polygonoMarkers[i] != lmarker; ++i);
            objMapControl.polygonoMarkers.splice(i, 1);
            objMapControl.pathPolygono.removeAt(i);
        });

        google.maps.event.addListener(lmarker, 'dragend', function () {
            for (var i = 0, I = objMapControl.polygonoMarkers.length; i < I && objMapControl.polygonoMarkers[i] != lmarker; ++i);
            objMapControl.pathPolygono.setAt(i, lmarker.getPosition());
        });
    }

    this.addGeoFenceMarkersClicBD = function (latLng) {
        objMapControl.pathPolygono.insertAt(objMapControl.pathPolygono.length, latLng);

        var lmarker = new google.maps.Marker({
            position: latLng,
            map: this.map,
            draggable: true
        });
        objMapControl.polygonoMarkers.push(lmarker);


        lmarker.setTitle("#" + objMapControl.pathPolygono.length);

        google.maps.event.addListener(lmarker, 'click', function () {
            lmarker.setMap(null);
            for (var i = 0, I = objMapControl.polygonoMarkers.length; i < I && objMapControl.polygonoMarkers[i] != lmarker; ++i);
            objMapControl.polygonoMarkers.splice(i, 1);
            objMapControl.pathPolygono.removeAt(i);
        });

        google.maps.event.addListener(lmarker, 'dragend', function () {
            for (var i = 0, I = objMapControl.polygonoMarkers.length; i < I && objMapControl.polygonoMarkers[i] != lmarker; ++i);
            objMapControl.pathPolygono.setAt(i, lmarker.getPosition());
        });
    }

    this.addMarker = function (image, position, title) {
        if (image == null) {
            return new google.maps.Marker({ map: this.map, position: position, title: title });
        }
        else {
            return new google.maps.Marker({ map: this.map, icon: image, position: position, title: title });
        }
    }

    this.addPosition = function (lat, lng) {
        return new google.maps.LatLng(lat, lng);
    }

    this.addImage = function (image) {
        return new google.maps.MarkerImage(images.location + image);
    }

    this.setCenterMap = function (position) {
        this.map.setCenter(position);
    }

    this.addListenerCustomerClick = function () {
        google.maps.event.addListener(this.map, 'click', this.addCustomerMarkersClic);
    }

    this.addCustomerMarkersClic = function (event) {
        global.customerMarker.setPosition(event.latLng);
        //objMapControl.isValidLocation(event.latLng.lat() + "," + event.latLng.lng());
        global.customerMarker.setDraggable(true);
    }

   
    this.calculateSmartRouteStart = function (address) {

        if (address == null) {
            address = this.originImeiMarker.position.lat() + "," + this.originImeiMarker.position.lng();
        }

        var geocoderRequest = {
            address: address
        }

        this.geocoderOrigin.geocode(geocoderRequest, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                global.originClient = results[0].geometry.location;
                //setTimeout(objMapControl.calculateSmartRouteProcess(globalList.allCustomers[global.currentIndexRoute].address),time);
                //setTimeout(objMapControl.calculateSmartRouteProcess, time);
                setTimeout(objMapControl.calculateSmartRouteProcess, global.timeToCalculateRouteClients);
            }
            else {
                //responseEnd(getrpvRoutesPanelUpdateControl());
                //msgValidation('CalculateSmartRouteStart - La posición no es una posición válida para luego generar rutas, colocar el marcador en la calle mas cercana.');
                if (nextPositionIndexRoute()) {
                    objMapControl.calculateSmartRouteProcess(globalList.allCustomers[global.currentIndexRoute].address);
                }
                else {//Se ignora y se vuelve a calcular
                    if (global.currentIndexNearClient != -1) {
                        calculateSmartRoute(globalList.allCustomers[global.currentIndexNearClient].address);
                    }
                    else {
                        calculateSmartRoute(null);
                    }
                }
            }
        });
    }

    this.calculateSmartRouteProcess = function () {
        address = globalList.allCustomers[global.currentIndexRoute].address;
        var geocoderRequest = {
            address: address
        }

        objMapControl.geocoderDestination.geocode(geocoderRequest, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                global.destinationClient = results[0].geometry.location;
                setTimeout(objMapControl.calculateSmartRouteValidation, global.timeToCalculateRouteClients);
            }
            else {
                //responseEnd(getrpvRoutesPanelUpdateControl());
                //msgValidation('CalculateSmartRouteProcess - La posición no es una posición válida para luego generar rutas, colocar el marcador en la calle mas cercana.');
                if (nextPositionIndexRoute()) {
                    setTimeout(objMapControl.calculateSmartRouteProcess, global.timeToCalculateRouteClients);
                }
                else {//Se ignora y se vuelve a calcular
                    if (global.currentIndexNearClient != -1) {
                        calculateSmartRoute(globalList.allCustomers[global.currentIndexNearClient].address);
                    }
                    else {
                        calculateSmartRoute(null);
                    }
                }
            }
        });
    }

    this.calculateSmartRouteValidation = function () {
        var request = {
            origin: global.originClient,
            destination: global.destinationClient,
            //waypoints: waypts,
            optimizeWaypoints: true,
            travelMode: google.maps.DirectionsTravelMode['DRIVING'],
            unitSystem: google.maps.DirectionsUnitSystem['METRIC'],
            provideRouteAlternatives: false
        };
        objMapControl.directionsService.route(request, function (response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                //objMapControl.showClientsRoutes();
                //alert(response.routes[0].legs[0].distance.value);

                if ((global.currentIndexNearClient == -1) || (response.routes[0].legs[0].distance.value < globalList.allCustomers[global.currentIndexNearClient].kms)) {
                    global.currentIndexNearClient = global.currentIndexRoute;
                    globalList.allCustomers[global.currentIndexNearClient].kms = response.routes[0].legs[0].distance.value;
                    globalList.allCustomers[global.currentIndexNearClient].kmsText = response.routes[0].legs[0].distance.text;
                    globalList.allCustomers[global.currentIndexNearClient].duration = response.routes[0].legs[0].duration.value;
                    globalList.allCustomers[global.currentIndexNearClient].durationText = response.routes[0].legs[0].duration.text;

                    global.route = response.routes[0];
                    

                    //globalList.allCustomers[global.currentIndexNearClient].numPos = ++global.numPos;
                    //addRowCustomersGroupsRouteDataSource(global.currentIndexNearClient);
                }
                
                if (nextPositionIndexRoute()) {
                    //if (global.currentIndexRoute < globalList.allCustomers.length) {
                    //setTimeout(objMapControl.calculateSmartRouteProcess, time);
                    setTimeout(objMapControl.calculateSmartRouteProcess, global.timeToCalculateRouteClients);
                    //}
                }
                else {//Es la mejor Ruta
                    globalList.allCustomers[global.currentIndexNearClient].numPos = ++global.numPos;
                    addRowCustomersGroupsRouteDataSource(global.currentIndexNearClient);
                    objMapControl.showClientsRoutes();
                    //alert(response.routes[0].legs[0].distance.text);

                    if (global.firstClientRoute) {
                        //objMapControl.clientsRoutes.push(response.routes[0]);
                        objMapControl.clientsRoutes.push(global.route);
                        global.firstClientRoute = false;
                    }
                    else {
                        objMapControl.clientsRoutes[0].legs.push(global.route.legs[0]);
                    }

                    response.routes = objMapControl.clientsRoutes;
                    objMapControl.drawRouteClient(response);

                    calculateSmartRoute(globalList.allCustomers[global.currentIndexNearClient].address);
                }
            }
            else {
                //responseEnd(getrpvRoutesPanelUpdateControl());
                //alert('No encontro ruta');
                if (nextPositionIndexRoute()) {
                    setTimeout(objMapControl.calculateSmartRouteProcess, global.timeToCalculateRouteClients);
                }
                else {//Se ignora y se vuelve a calcular
                    if (global.currentIndexNearClient != -1) {
                        calculateSmartRoute(globalList.allCustomers[global.currentIndexNearClient].address);
                    }
                    else {
                        calculateSmartRoute(null);
                    }
                }
            }
        });
    }

    /*this.getValidOriginLocation = function (address) {
        var geocoderRequest = {
            address: address
        }

        this.geocoderOrigin.geocode(geocoderRequest, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                global.originClient = results[0].geometry.location;
                if (nextPositionIndexRoutetoDraw()) {
                    objMapControl.getValidDestinationLocation(globalList.allCustomers[global.currentIndexRoute].address);
                }
                else {
                    responseEnd(getrpvRoutesPanelUpdateControl());
                }
            }
            else {
                responseEnd(getrpvRoutesPanelUpdateControl());
                msgValidation('La posición de Origen no es una posición válida para generar rutas, colocar el marcador en la calle mas cercana.');
            }
        });
    }*/

    /*this.getValidDestinationLocation = function (address) {
        var geocoderRequest = {
            address: address
        }

        this.geocoderDestination.geocode(geocoderRequest, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                global.destinationClient = results[0].geometry.location;
                objMapControl.getClientRoute();
            }
            else {
                responseEnd(getrpvRoutesPanelUpdateControl());
                msgValidation('La posición no es una posición válida para luego generar rutas, colocar el marcador en la calle mas cercana.');
            }
        });
    }*/

    this.clearStopsMarkers = function() {
        var length = globalList.stopsMarkers.length;

        for (i = 0; i < length; i++) {
            globalList.stopsMarkers[i].stopMarker.setMap(null);
        }

        for (i = 0; i < length; i++) {
            globalList.stopsMarkers.pop();
        }
    }

    this.getDrivingRoute = function () {
        var request = {
            origin: global.origin,
            destination: global.destination,
            //waypoints: waypts,
            optimizeWaypoints: true,
            travelMode: google.maps.DirectionsTravelMode['DRIVING'],
            unitSystem: google.maps.DirectionsUnitSystem['METRIC'],
            provideRouteAlternatives: false
        };
        objMapControl.directionsService.route(request, function (response, status) {
            if (status == google.maps.DirectionsStatus.OK) {

                if (global.firstRoute) {
                    objMapControl.routes.push(response.routes[0]);
                    global.firstRoute = false;
                }
                else {
                    for (var i = 0; i < response.routes[0].legs[0].steps.length; i++) {
                        objMapControl.routes[0].legs[0].steps.push(response.routes[0].legs[0].steps[i]);
                    }
                    objMapControl.routes[0].legs[0].end_location = objMapControl.getPositionMarker(globalList.trackDataByImei[global.currentGpsPoint + 1]);
                }

                response.routes = objMapControl.routes;
            
                objMapControl.drawRoute(response);
            
                if (!global.lastOne) {
                    if (getCkbSiNoCenterRoute().checked) {
                        objMapControl.map.setCenter(objMapControl.routes[0].legs[0].end_location);
                    }
                }
                global.doesWorkDrawRouteCount = 0;
                global.mtsRoute = global.mtsRouteStar;
            }
            else {
                global.doesnWorkDrawRoute = true;
                if (global.doesWorkDrawRouteCount > 5) {
                    global.mtsRoute = global.mtsRouteFix;
                }
                global.doesWorkDrawRouteCount++;
            
                //alert('No encontro ruta');
            }

        });
    }

    /*this.getClientRoute = function () {
        var request = {
            origin: global.originClient,
            destination: global.destinationClient,
            //waypoints: waypts,
            optimizeWaypoints: true,
            travelMode: google.maps.DirectionsTravelMode['DRIVING'],
            unitSystem: google.maps.DirectionsUnitSystem['METRIC'],
            provideRouteAlternatives: false
        };
        objMapControl.directionsService.route(request, function (response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                objMapControl.showClientsRoutes();
                //alert(response.routes[0].legs[0].distance.text);

                if (global.firstClientRoute) {
                    objMapControl.clientsRoutes.push(response.routes[0]);
                    global.firstClientRoute = false;
                }
                else {
                    objMapControl.clientsRoutes[0].legs.push(response.routes[0].legs[0]);
                }

                response.routes = objMapControl.clientsRoutes;

                
                objMapControl.drawRouteClient(response);

                global.originClient = global.destinationClient;

                if (nextPositionIndexRoutetoDraw()) {
                    objMapControl.getValidDestinationLocation(globalList.allCustomers[global.currentIndexRoute].address);
                }
                else {
                    responseEnd(getrpvRoutesPanelUpdateControl());
                }
            }
            else {
                alert('No encontro ruta');
            }
        });
    }*/

    this.getDistanceKms = function (pinitialPosition, pfinalPosition) {

        var distance = google.maps.geometry.spherical.computeDistanceBetween(pinitialPosition, pfinalPosition);
        return distance / 1000.00;
    }

    this.addEventsDrag = function (pMyCar) {

        pMyCar.setDraggable(true);
        // Add dragging event listeners.
        google.maps.event.addListener(pMyCar, 'dragstart', function () {
            updateDirectionMarker('Dragging...');
        });

        google.maps.event.addListener(pMyCar, 'drag', function () {
            //updateMarkerStatus('Dragging...');
        });

        google.maps.event.addListener(pMyCar, 'dragend', function () {
            //updateMarkerStatus('Drag ended');
            objMapControl.getDirectionFromPosition(pMyCar.getPosition());
        });
    }

    this.getPositionYtoString = function (position) {
        return configDecimalSeparator(position.lng().toString());
    }

    this.getPositionXtoString = function (position) {
        return configDecimalSeparator(position.lat().toString());
    }
}

function GeoFence() {

    var geoFenceID = "";
    var description = "";
    var imei = "";
    var polygono = "";
    var polygonoMarkers = [];
    var pathPolygono = new google.maps.MVCArray;

    this.numPosList = [];
    this.latitudeList = [];
    this.longitudeList = [];

    this.checked = false;

    this.showGeoFence = function () {

        var position;

        this.polygono.setMap(objMapControl.map);
        this.polygono.setPaths(new google.maps.MVCArray([this.pathPolygono]));

        for (h = 0; h < this.numPosList.length; h++) {
            position = new google.maps.LatLng(stringToFloatForPosition(this.latitudeList[h]), stringToFloatForPosition(this.longitudeList[h]));
            this.pathPolygono.insertAt(this.pathPolygono.length, position);
        }
    };

    this.hideGeoFence = function () {
        this.pathPolygono.clear();
    };

    this.createGeoFence = function (pgeoFenceID, pdescription, pimei, pnumPosList, platitudeList, plongitudeList) {

        this.updateGeoFence(pgeoFenceID, pdescription, pimei, pnumPosList, platitudeList, plongitudeList);

        this.polygono = new google.maps.Polygon({
            strokeWeight: 3,
            fillColor: '#5555FF'
        });

        this.pathPolygono = new google.maps.MVCArray;
    };

    this.updateGeoFence = function (pgeoFenceID, pdescription, pimei, pnumPosList, platitudeList, plongitudeList) {

        this.geoFenceID = pgeoFenceID;
        this.description = pdescription;
        this.imei = pimei;
        this.numPosList = pnumPosList;
        this.latitudeList = platitudeList;
        this.longitudeList = plongitudeList;
    };
}